package org.bing.engine.console.service;

public class LevelCodeManager {

    // TODO impl dynamic level
    private String block = "00000000";
    private String first = "00000001";
    private String fully = "0000000000000000000000000000000000000000";

    public String getFirstCode() {
        String temp = first + fully;
        return temp.substring(0, 40);
    }

    public String calcNext(String maxCode) {
        validate(maxCode);
        if (maxCode.length() != 40) {
            throw new RuntimeException("Max code format error! " + maxCode);
        }
        while (maxCode.endsWith(block)) {
            maxCode = maxCode.substring(0, maxCode.length() - block.length());
        }
        String code = maxCode.equals("") ? block : maxCode;
        String part = code.substring(code.length() - block.length());
        int next = Integer.parseInt(part) + 1;
        if (next > 99999999) {
            throw new RuntimeException("Current level is fully! " + maxCode);
        }
        part = block + next;
        part = part.substring(part.length() - block.length());
        String result = code.substring(0, code.length() - 8) + part + fully;
        return result.substring(0, 40);
    }

    public String calcFirstChild(String parentCode) {
        validate(parentCode);
        while (parentCode.endsWith(block)) {
            parentCode = parentCode.substring(0, parentCode.length() - block.length());
        }
        if (parentCode != null && parentCode.length() == 40) {
            throw new RuntimeException("Max level is reached!");
        }
        String code = parentCode.equals("") ? block : parentCode;
        code = code + first + fully;
        return code.substring(0, 40);
    }

    public String calcPrefixCode(String code) {
        validate(code);
        while (code.endsWith(block)) {
            code = code.substring(0, code.length() - block.length());
        }
        return code;
    }

    // TODO more better, include content,A-F etc
    private void validate(String code) {
        boolean flag = true;
        if (code == null || code.length() != 40) {
            flag = false;
        }
        for (int i = 0; i < 40; i++) {
            Character c = code.charAt(i);
            if (!Character.isLetterOrDigit(c)) {
                flag = false;
            }
        }
        if (!flag) {
            throw new RuntimeException("Code format error! " + code);
        }
    }

    public String format(String code) {
        if (code == null || code.length() != 40) {
            return code;
        }
        StringBuilder sb = new StringBuilder(50);
        for (int i = 0; i < 5; i++) {
            sb.append(code.substring(i * 8, (i + 1) * 8));
            if (i != 4) {
                sb.append("-");
            }
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        LevelCodeManager mgr = new LevelCodeManager();
        String curr = "0000000000007000000000000000000000000000";
        String next = mgr.calcNext(curr);
        System.out.println(mgr.format(curr));
        System.out.println(mgr.format(next));
        System.out.println(mgr.format(mgr.calcNext(next)));
        System.out.println("--------------------------------------------");
        // "0000000A0000000A0000000A0000000A0000000A"
        String parent = "0000000000800000000000000000000000000000";
        String child = mgr.calcFirstChild(parent);
        System.out.println(mgr.format(parent));
        System.out.println(mgr.format(mgr.calcFirstChild(child)));
    }
}
